package com.woniu.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.config.BloomRedisConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

import static com.woniu.config.BloomFilterConfig.BLOOM_STRING_FILTER;

/**
 * 布隆过滤器 - 拦截过滤
 *
 * @author zrh
 */
@Slf4j
@Component
public class BloomFilterInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private BloomRedisConfig bloomRedisService;

    /**
     * 自定义拦截过滤方法
     *
     * @param request
     * @param response
     * @param o
     * @return
     * @throws IOException
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws IOException {
        // 如果是OPTIONS则结束请求
        if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
            response.setStatus(HttpStatus.NO_CONTENT.value());
            return true;
        }
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        // 获取参数
        String id = request.getParameter("id");
        if (id == null) {
            String currentUrl = request.getRequestURI();
            PathMatcher matcher = new AntPathMatcher();
            Map<String, String> pathVariable = matcher.extractUriTemplateVariables("/product/{id}", currentUrl);
            id = pathVariable.get("id");
        }

        log.info("进入布隆过滤器拦截器。。。");
        // 使用guava布隆过滤器进行拦截过滤
//        if (LocalBloomFilter.match(id)) {
//            return true;
//        }

        // 在redis中使用布隆过滤器
        if (bloomRedisService.includeByBloomFilter(BLOOM_STRING_FILTER, id)) {
            String result = new ObjectMapper().writeValueAsString("，参数存在：" + id);
            response.getWriter().print(result);
            return true;
        }

        // 不在本地布隆过滤器当中，直接返回验证失败。设置响应头
        response.setHeader("Content-Type", "application/json");
        response.setCharacterEncoding("UTF-8");
        String result = new ObjectMapper().writeValueAsString("布隆过滤器拦截，参数不存在：" + id);
        response.getWriter().print(result);
        return false;
    }
}
